package com.ccnf.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ccnf.core.bean.StatusCode;
import com.ccnf.core.bean.TokenParams;
import com.ccnf.core.exception.BizException;
import com.ccnf.core.utils.ResultUtil;
import com.ccnf.core.utils.ShareCodeUtil;
import com.ccnf.model.entity.Authorization;
import com.ccnf.model.entity.ExpoUser;
import com.ccnf.model.entity.SocialUser;
import com.ccnf.model.entity.UserApply;
import com.ccnf.model.enums.ApplyStatusEnum;
import com.ccnf.model.enums.AuthModeEnum;
import com.ccnf.model.enums.AuthStatusEnum;
import com.ccnf.model.enums.RoleTypeEnum;
import com.ccnf.model.mapper.AuthorizationMapper;
import com.ccnf.model.mapper.ExpoUserMapper;
import com.ccnf.model.mapper.SocialUserMapper;
import com.ccnf.model.mapper.UserApplyMapper;
import com.ccnf.model.vo.ApplyVO;
import com.ccnf.model.vo.AuthUserVO;
import com.ccnf.model.vo.UserVO;
import com.ccnf.service.SaasService;
import com.ccnf.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * <p>
 * 用户社交信息表 服务实现类
 * </p>
 *
 * @author developer
 * @since 2018-10-09
 */
@Service
public class UserServiceImpl extends ServiceImpl<SocialUserMapper, SocialUser> implements UserService {
    @Autowired
    private ExpoUserMapper expoUserMapper;
    @Autowired
    private AuthorizationMapper authorizationMapper;
    @Autowired
    private UserApplyMapper userApplyMapper;
    @Autowired
    private SaasService saasService;

    @Override
    @Transactional
    public Long saveSocialUser(Long expoId, SocialUser socialUser) {
        SocialUser selectSocialUser = baseMapper.selectByOpenId(socialUser.getOpenId());// 通过用户的openId查询用户信息
        if (selectSocialUser == null) {
            // 不存在用户数据
            ResultUtil.validateSQL(baseMapper.insert(socialUser), "用户信息录入失败");
            return socialUser.getId();
        }  else {
            boolean isUpdate = false;
            if (!selectSocialUser.getHeadImage().equals(socialUser.getHeadImage())){
                selectSocialUser.setHeadImage(socialUser.getHeadImage());
                isUpdate = true;
            }
            if (!selectSocialUser.getNickname().equals(socialUser.getNickname())) {
                selectSocialUser.setNickname(socialUser.getNickname());
                isUpdate = true;
            }
            if (isUpdate) {
                ResultUtil.validateSQL(baseMapper.updateById(selectSocialUser), "更新用户信息失败");
            }
        }
        return selectSocialUser.getId();
    }

    @Override
    public String createRoleAuth(TokenParams tokenParams, Authorization authorization) {
        Long expoId = tokenParams.getExpoId();// 展会ID
        Long userId = tokenParams.getUserId();// 授权用户ID
        RoleTypeEnum roleTypeEnum = authorization.getRoleType();
        ExpoUser expoUser = expoUserMapper.selectExpoUser(expoId, userId);// 查询授权人角色信息
        if (expoUser.getRoleType().getRoleType() < roleTypeEnum.getRoleType()) {
            throw new BizException("权限不足");
        } else  {
            AuthModeEnum authMode = authorization.getAuthMode();
            String phone = authorization.getPhone();
            switch (authMode) {
                case WEI_XIN:
                    break;
                case SMS:
                    if (StringUtils.isEmpty(phone)) {
                        throw new BizException("手机号不能为空");
                    }
                    Authorization selectAuth = new Authorization();
                    selectAuth.setExpoId(expoId);
                    selectAuth.setPhone(phone);
                    selectAuth.setRoleType(roleTypeEnum);
                    Authorization select = authorizationMapper.selectOne(new QueryWrapper<>(selectAuth));
                    if (select != null) {
                        throw new BizException("该手机号已授权，请勿重复授权");
                    }
                    break;
            }
            authorization.setAuthStatus(AuthStatusEnum.AWAIT);
            authorization.setExpoId(expoId);
            ResultUtil.validateSQL(authorizationMapper.insert(authorization), "生成授权码失败");
            if (authMode.equals(AuthModeEnum.SMS)) {
                saasService.saasSendSms(expoId, phone, "尊敬的用户你好，你的好友\"" +
                        baseMapper.selectById(userId).getNickname() + "\"" + "邀请您加入邀请函应用管理，请关注公众号【会管家】，点击进入H5邀请函，输入您的手机号码：" + phone + "登录。如有疑问可以致电："
                + expoUser.getPhone());
            }
            return ShareCodeUtil.idToCode(authorization.getId());
        }
    }

    @Override
    public UserVO findUserInfo(TokenParams tokenParams) {
        UserVO userVO = baseMapper.selectUserInfo(tokenParams.getExpoId(), tokenParams.getUserId());
        return userVO;
    }

    @Override
    public List<AuthUserVO> listAuth(TokenParams tokenParams) {
        return authorizationMapper.selectAuthList(tokenParams.getExpoId());
    }

    @Override
    @Transactional
    public void relieveAuth(String authCode, TokenParams tokenParams) {
        Long expoId = tokenParams.getExpoId();
        Long userId = tokenParams.getUserId();
        Authorization authorization = authorizationMapper.selectById(authCode);
        ResultUtil.validateNull(authorization, "授权信息不存在");
        if (!authorization.getExpoId().equals(expoId)) {
            throw new BizException("展会信息不匹配");
        }
        RoleTypeEnum roleType = authorization.getRoleType();
        switch (roleType) {
            case EXHIBITOR:
                break;
            case MANAGER:
                break;
        }
        if (!authorization.getUserId().equals(userId)) {
            ExpoUser expoUser = expoUserMapper.selectExpoUser(expoId, authorization.getUserId());
            expoUser.setRoleType(RoleTypeEnum.USER);
            expoUserMapper.updateById(expoUser);
        }
        authorization.setAuthStatus(AuthStatusEnum.NONE);
        authorizationMapper.updateById(authorization);
    }

    @Override
    public void validateRole(TokenParams tokenParams, RoleTypeEnum[] roleTypeEnums) {
        Long expoId = tokenParams.getExpoId();
        Long userId = tokenParams.getUserId();
        ExpoUser eu = expoUserMapper.selectExpoUser(expoId, userId);
        for (RoleTypeEnum roleTypeEnum: roleTypeEnums) {
            if (eu.getRoleType().equals(roleTypeEnum)) {
                return;
            }
        }
        throw new BizException(StatusCode.NO_PERMISSION, "权限不够");
    }

    @Override
    public void saveUserApply(UserApply apply, TokenParams tokenParams) {
        UserApply selectUserApply = new UserApply();
        selectUserApply.setExpoId(tokenParams.getExpoId());
        selectUserApply.setUserId(tokenParams.getUserId());
        UserApply select = userApplyMapper.selectOne(new QueryWrapper<>(selectUserApply));
        if (select == null) {
            selectUserApply.setApplyStatus(ApplyStatusEnum.AWAIT);
            selectUserApply.setApplyInfo(apply.getApplyInfo());
            userApplyMapper.insert(selectUserApply);
        } else if (select.getApplyStatus().equals(ApplyStatusEnum.FAILURE)){
            select.setApplyInfo(apply.getApplyInfo());
            select.setApplyStatus(ApplyStatusEnum.AWAIT);
            userApplyMapper.updateById(select);
        } else {
            throw new BizException("请不要重复提交信息");
        }
    }

    @Override
    public ApplyVO findUserApplyInfo(TokenParams tokenParams) {
        return userApplyMapper.selectUserApplyInfo(tokenParams.getExpoId(), tokenParams.getUserId());
    }

    @Override
    public List<ApplyVO> listUserApply(ApplyStatusEnum applyStatus, TokenParams tokenParams) {
        return userApplyMapper.selectUserApplyList(tokenParams.getExpoId(), applyStatus.getApplyStatus());
    }

    @Override
    public void handleUserApplyAudit(Long applyId, ApplyStatusEnum applyStatus) {
        UserApply userApply = userApplyMapper.selectById(applyId);
        ApplyStatusEnum selectApplyStatus = userApply.getApplyStatus();
        switch (selectApplyStatus) {
            case AWAIT:
                userApply.setApplyStatus(applyStatus);
                userApplyMapper.updateById(userApply);
                break;
            case SUCCESS:
                throw new BizException("申请已通过");
            case FAILURE:
                throw new BizException("申请已拒绝");
            case OVER:
                throw new BizException("申请已过期");
        }
    }
}